import { defineStore } from "pinia";

import {
  loginApi,
  loginQrcode,
  logoutApi,
  refreshTokenApi,
  getUserInfoApi,
  loginOrganApi,
  registerApi,
} from "@/api/auth";
import { listRoles } from "@/api/auth/index";
import { resetRouter } from "@/router";
import { store } from "@/stores";

import type {
  UserStoreInfo,
  LoginData,
  LoginQrcodeReq,
  UserInfo,
  RolesPerms,
  RegisterReq,
  LoginResult,
} from "@/api/auth/types";

import { useStorage } from "@vueuse/core";
import { vueMetaEnv } from "@/settings";

export const useUserStore: any = defineStore("user", () => {
  const user: UserStoreInfo = {
    tenant: "", // 租户
    roleCodes: [],
    permCodes: [],
  };

  const token = useStorage("accessToken", "");
  const userToken: any = useStorage("userToken", {});
  /**
   * 登录
   *
   * @param {LoginData}
   * @returns
   */
  function login(loginData: LoginData) {
    return new Promise<LoginResult>((resolve, reject) => {
      loginApi(loginData)
        .then(({ data }) => {
          token.value = data.accessToken; // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx
          data.expiresDate = new Date().getTime() + data.expiresIn * 1000;
          userToken.value = data;
          resolve(data);
        })
        .catch((error) => {
          console.log(error);
          reject(error);
        });
    });
  }

  /**
   * 登录
   *
   * @param {RegisterReq}
   * @returns
   */
  function register(registerData: RegisterReq) {
    return new Promise<LoginResult>((resolve, reject) => {
      registerApi(registerData)
        .then(({ data }) => {
          token.value = data.accessToken; // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx
          data.expiresDate = new Date().getTime() + data.expiresIn * 1000;
          userToken.value = data;
          resolve(data);
        })
        .catch((error) => {
          console.log(error);
          reject(error);
        });
    });
  }

  /**
   * 登录组织，用户tenant换组织用户Token
   *
   * @param tenant
   * @returns
   */
  function loginOrgan(tenant: string) {
    return new Promise<void>((resolve, reject) => {
      loginOrganApi(tenant)
        .then(({ data }) => {
          token.value = data.accessToken;
          data.expiresDate = new Date().getTime() + data.expiresIn * 1000;
          userToken.value = data;
          resolve();
        })
        .catch((error) => {
          console.log(error);
          reject(error);
        });
    });
  }

  /**
   * 扫码登录
   */
  function loginByQrcode(loginData: LoginQrcodeReq) {
    return new Promise<LoginResult>((resolve, reject) => {
      loginQrcode(loginData)
        .then(({ data }) => {
          if (data.accessToken) {
            token.value = data.accessToken; // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx
            data.expiresDate = new Date().getTime() + data.expiresIn * 1000;
            userToken.value = data;
            resolve(data);
          } else {
            reject("未扫码");
          }
        })
        .catch((error) => {
          console.log(error);
          reject(error);
        });
    });
  }

  //是否Token过期.
  function isTokenExpires(): boolean {
    if (userToken.value && userToken.value["expiresDate"]) {
      const now = new Date().getTime();
      //提前1分钟过期.
      return now + 60000 > userToken.value["expiresDate"];
    }
    return false;
  }

  // 获取信息(用户昵称、头像、角色集合、权限集合)
  function getUserInfo() {
    return new Promise<UserInfo>((resolve, reject) => {
      getUserInfoApi()
        .then(({ data }) => {
          if (!data) {
            reject("Verification failed, please Login again.");
            return;
          }
          Object.assign(user, { ...data });
          resolve(data);
        })
        .catch((error) => {
          reject(error);
        });
    });
  }

  // 获取角色权限
  function getRoleInfo(): Promise<RolesPerms> {
    return new Promise<RolesPerms>((resolve, reject) => {
      listRoles()
        .then(({ data }) => {
          if (!data) {
            reject("Verification failed, please Login again.");
            return;
          }
          //无角色，默认角色#
          if (data.roleCodes && data.roleCodes.length == 0) {
            data.roleCodes = ["#"];
          }
          Object.assign(user, { ...data });
          resolve(data);
        })
        .catch((error) => {
          reject(error);
        });
    });
  }

  // 刷新Token
  function refreshToken(tokenParam: string) {
    return new Promise<string>((resolve, reject) => {
      refreshTokenApi(tokenParam)
        .then((response: any) => {
          const { accessToken } = response.data;
          token.value = accessToken; // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx
          response.data["expiresDate"] =
            new Date().getTime() + response.data["expiresIn"] * 1000;
          userToken.value = response.data;
          resolve(token.value);
        })
        .catch((error) => {
          token.value = "";
          userToken.value = {};
          console.log(error);
          reject(error);
        });
    });
  }

  // user logout
  function logout() {
    return new Promise<void>((resolve, reject) => {
      logoutApi(token.value)
        .then(() => {
          token.value = "";
          user.roleCodes = [];
          user.permCodes = [];
          userToken.value = {};
          // location.reload(); // 清空路由
          resolve();
        })
        .catch((error) => {
          reject(error);
        });
    });
  }

  // remove token
  function resetToken() {
    return new Promise<void>((resolve) => {
      token.value = "";
      userToken.value = {};
      resetRouter();
      resolve();
    });
  }

  return {
    token,
    user,
    userToken,
    login,
    loginByQrcode,
    getUserInfo,
    logout,
    resetToken,
    isTokenExpires,
    refreshToken,
    getRoleInfo,
    loginOrgan,
    register,
  };
});

// 非setup
export function useUserStoreHook() {
  return useUserStore(store);
}
